//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Query Application Block
//===============================================================================

using System;
using System.Data;
using System.Configuration;
using EntLibContrib.Query.Parameters;

namespace EntLibContrib.Query.Configuration
{
    using System.Collections.Generic;
    using Database.Properties;
    using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ContainerModel;
    using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Design;

    /// <summary>
	/// Type to hold the elements of a single query parameter
	/// </summary>
    [ResourceDescription(typeof(DesignResources), "DataParameterDataDescription")]
    [ResourceDisplayName(typeof(DesignResources), "DataParameterDataDisplayName")]
    public class DataParameterData : ParameterData
	{
		private const string dbTypeProperty = "dbType";
		private const string directionProperty = "direction";

		/// <summary>
		/// Gets or sets the type of the parameter.
		/// </summary>
		/// <value>The type of the parameter.</value>
		[ConfigurationProperty(dbTypeProperty, IsRequired = true)]
        [ResourceDescription(typeof(DesignResources), "DataParameterDataDbTypeDescription")]
        [ResourceDisplayName(typeof(DesignResources), "DataParameterDataDbTypeDisplayName")]
		public DbType DbType
		{
			get { return (DbType)base[dbTypeProperty]; }
			set { base[dbTypeProperty] = value; }
		}

		/// <summary>
		/// Gets or sets the parameter direction.
		/// </summary>
		/// <value>The parameter direction.</value>
		/// <remarks>the directions are In or Out</remarks>
		[ConfigurationProperty(directionProperty, IsRequired = true, DefaultValue = ParameterDirection.Input)]
        [ResourceDescription(typeof(DesignResources), "DataParameterDataDirectionDescription")]
        [ResourceDisplayName(typeof(DesignResources), "DataParameterDataDirectionDisplayName")]
		public ParameterDirection Direction
		{
			get { return (ParameterDirection)base[directionProperty]; }
			set { base[directionProperty] = value; }
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="DataParameterData"/> class.
		/// </summary>
		public DataParameterData()
            : this(null, typeof(DataParameter))
		{
		}

        /// <summary>
        /// Initializes a new instance of the <see cref="DataParameterData"/> class.
        /// </summary>
        public DataParameterData(string name, Type type)
            : base(name, type)
        {
        }

		/// <summary>
		/// Initializes a new instance of the <see cref="DataParameterData"/> class.
		/// </summary>
		/// <param name="name">The parameter name.</param>
		/// <param name="dbType">Type of the parameter.</param>
		/// <param name="direction">The direction of the parameter relative to the data source.</param>
		public DataParameterData(
			string name,
			DbType dbType,
			ParameterDirection direction
			)
			: base(name, typeof(DataParameter))
		{
			this.DbType = dbType;
			this.Direction = direction;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="DataParameterData"/> class.
		/// </summary>
		/// <param name="name">The parameter name.</param>
		/// <param name="type">The type.</param>
		/// <param name="dbType">Type of the parameter.</param>
		/// <param name="direction">The direction of the parameter relative to the data source.</param>
		protected DataParameterData(
			string name,
			Type type,
			DbType dbType,
			ParameterDirection direction
			)
			: base(name, type)
		{
			this.DbType = dbType;
			this.Direction = direction;
		}

        /// <summary>
        /// A <see cref="TypeRegistration"/> container configuration model for <see cref="NameValueParameterData"/>.
        /// </summary>
        /// <param name="name">The name to use when determining references to child elements.</param>
        /// <returns>A <see cref="TypeRegistration"/> for registering a <see cref="DataParameterData"/> in the container.</returns>
        public override IEnumerable<TypeRegistration> GetRegistrations(string name)
        {
            yield return
                new TypeRegistration<IParameter>(
                    () => new DataParameter(
                        Name, 
                        DbType, 
                        Direction))
                {
                    Lifetime = TypeRegistrationLifetime.Transient,
                    Name = name,
                    IsPublicName = false
                };
        }
	}
}
